package com.it.flowable.model;

import com.it.flowable.listener.AdvancedFlowableListener;
import com.it.flowable.listener.MyExecutionListener;
import com.it.flowable.listener.MyJavaDelegate;
import com.it.flowable.listener.MyTaskListener;
import com.it.flowable.util.DataUtils;
import com.it.flowable.util.ExtensionElementUtils;
import com.it.flowable.util.ListenerUtils;
import com.it.flowable.util.Utils;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;

import java.util.*;

import static com.it.flowable.util.FieldExtensionUtils.createFieldExtension;

public class FourLevelModel {

    // 流程常量定义
    public static final String PROCESS_KEY = "FourLevelModel";
    public static final String PROCESS_NAME = "FourLevelModel";

    // 任务定义
    public static final String TASK_START = "start";
    public static final String APPLY_TASK = "applyTask";
    public static final String TASK_LEADER_APPROVAL = "leaderApproval";
    public static final String TASK_DEPT_MANAGER_APPROVAL = "deptManagerApproval";
    public static final String TASK_HR_APPROVAL = "hrApproval";
    public static final String TASK_CEO_APPROVAL = "ceoApproval";
    public static final String TASK_NOTIFY = "notifyTask";
    public static final String TASK_END = "end";

    // 网关定义
    public static final String GATEWAY_LEADER_DECISION = "leaderDecision";
    public static final String GATEWAY_HR_DECISION = "hrDecision";
    public static final String GATEWAY_DEPT_MANAGER_DECISION = "deptManagerDecision";
    public static final String GATEWAY_CEO_DECISION = "ceoDecision";

    // 监听器
    public static final String EXECUTION_LISTENER = MyExecutionListener.class.getName();
    public static final String TASK_LISTENER = MyTaskListener.class.getName();
    public static final String JAVA_DELEGATE = MyJavaDelegate.class.getName();
    public static final String ADVANCED_TASK_LISTENER = AdvancedFlowableListener.class.getName();
    public static final Collection<? extends FieldExtension> FIELD_EXTENSIONS = createFieldExtensions();

    public static List<FieldExtension> createFieldExtensions() {
        FieldExtension fieldExtension = createFieldExtension("name", "value");
        FieldExtension fieldExtension2 = createFieldExtension("age", "18");
        return Arrays.asList(fieldExtension, fieldExtension2);
    }
    /**
     * 创建完整的四级审批流程（包含驳回功能）
     */
    public static BpmnModel create() {
        BpmnModel model = new BpmnModel();
        Process process = new Process();
        process.setId(PROCESS_KEY);
        process.setName(PROCESS_NAME);
        model.addProcess(process);

        // 创建所有节点
        // 任务节点
        Event startEvent = Utils.createStartEvent(TASK_START, "开始事件", null, null, null, null);
        UserTask submitTask = Utils.createUserTask(APPLY_TASK, "填写请假申请", "${initiator}", null, null, null, null);
        UserTask leaderTask = createUserTask(TASK_LEADER_APPROVAL, "直属领导审批", "${leaderAssignee}", "${candidateGroups}", null, null);
        UserTask deptTask = createUserTask(TASK_DEPT_MANAGER_APPROVAL, "部门经理审批", "${deptManagerAssignee}", null, null, null);
        UserTask task = createUserTask(TASK_HR_APPROVAL, "HR合规审查", "${hrAssignee}", null, DataUtils.createHrFormProperties(), "HR_REVIEW");
        UserTask ceoTask = createUserTask(TASK_CEO_APPROVAL, "CEO审批", "${ceoAssignee}", null, null, null);
        ServiceTask serviceTask = Utils.createServiceTask(TASK_NOTIFY, "发送审批结果通知", JAVA_DELEGATE, FIELD_EXTENSIONS);
        Event endEvent = Utils.createEndEvent(TASK_START, "开始事件");


        // 网关节点
        ExclusiveGateway exclusiveGateway = Utils.createExclusiveGateway(GATEWAY_LEADER_DECISION, "直属领导审批决策");
        ExclusiveGateway exclusiveGateway1 = Utils.createExclusiveGateway(GATEWAY_DEPT_MANAGER_DECISION, "部门经理审批决策");
        ExclusiveGateway exclusiveGateway2 = Utils.createExclusiveGateway(GATEWAY_HR_DECISION, "HR审批决策");
        ExclusiveGateway exclusiveGateway3 = Utils.createExclusiveGateway(GATEWAY_CEO_DECISION, "CEO审批决策");

        List<FlowElement> elements = Arrays.asList(
                startEvent,
                submitTask,
                leaderTask,
                deptTask,
                task,
                ceoTask,
                serviceTask,
                endEvent
        );
        List<ExclusiveGateway> gateways = Arrays.asList(exclusiveGateway, exclusiveGateway1, exclusiveGateway2, exclusiveGateway3);

        // 添加所有元素到流程
        elements.forEach(process::addFlowElement);
        gateways.forEach(process::addFlowElement);

        // 创建序列流

        List<SequenceFlow> flows = Arrays.asList(
                // 正常流程
                Utils.createSequenceFlow(TASK_START, APPLY_TASK, "提交申请", "${approveResult == 'REJECT'}", null),
                Utils.createSequenceFlow(APPLY_TASK, TASK_LEADER_APPROVAL, "提交申请", "${approveResult == 'REJECT'}", null),
                Utils.createSequenceFlow(TASK_LEADER_APPROVAL, GATEWAY_LEADER_DECISION, null, "${approveResult == 'REJECT'}", null),
                Utils.createSequenceFlow(TASK_DEPT_MANAGER_APPROVAL, GATEWAY_DEPT_MANAGER_DECISION, null, "${approveResult == 'REJECT'}", null),
                Utils.createSequenceFlow(TASK_HR_APPROVAL, GATEWAY_HR_DECISION, null, "${approveResult == 'REJECT'}", null),
                Utils.createSequenceFlow(TASK_CEO_APPROVAL, GATEWAY_CEO_DECISION, null, "${approveResult == 'REJECT'}", null),
                Utils.createSequenceFlow(TASK_NOTIFY, TASK_END, "流程结束", "${approveResult == 'REJECT'}", null),

                // 领导审批决策
                Utils.createSequenceFlow(GATEWAY_LEADER_DECISION, TASK_DEPT_MANAGER_APPROVAL, "审批通过", "${approveResult == 'APPROVE'}", null),
                Utils.createSequenceFlow(GATEWAY_LEADER_DECISION, TASK_START, "审批驳回", "${approveResult == 'REJECT'}", null),

                // 部门经理审批决策
                Utils.createSequenceFlow(GATEWAY_DEPT_MANAGER_DECISION, TASK_HR_APPROVAL, "审批通过", "${approveResult == 'APPROVE'}", null),
                Utils.createSequenceFlow(GATEWAY_DEPT_MANAGER_DECISION, TASK_LEADER_APPROVAL, "审批驳回", "${approveResult == 'REJECT'}", null),

                // HR审批决策
                Utils.createSequenceFlow(GATEWAY_HR_DECISION, TASK_CEO_APPROVAL, "大于3天需CEO审批", "${days > 3 && approveResult == 'APPROVE'}", null),
                Utils.createSequenceFlow(GATEWAY_HR_DECISION, TASK_NOTIFY, "3天以内直接通过", "${days <= 3 && approveResult == 'APPROVE'}", null),
                Utils.createSequenceFlow(GATEWAY_HR_DECISION, TASK_DEPT_MANAGER_APPROVAL, "审批驳回", "${approveResult == 'REJECT'}", null),

                // CEO审批决策
                Utils.createSequenceFlow(GATEWAY_CEO_DECISION, TASK_NOTIFY, "审批通过", "${approveResult == 'APPROVE'}", null),
                Utils.createSequenceFlow(GATEWAY_CEO_DECISION, TASK_HR_APPROVAL, "审批驳回", "${approveResult == 'REJECT'}", null)
        );

        flows.forEach(process::addFlowElement);

        return model;
    }


    /**
     * 创建通用审批任务
     */
    public static UserTask createUserTask(String id, String name, String assignee, String candidateGroups, List<FormProperty> formProperties, String category) {
        UserTask task = Utils.createUserTask(id, name, assignee, category, null, null, null);

        if (candidateGroups != null) {
            task.setCandidateGroups(Arrays.asList(candidateGroups));
        }

        ListenerUtils.addAdvancedTaskListener(task);


        List<Map<String, String>> dataList = AdvancedFlowableListener.MessageType.getMap();

        for (Map<String, String> map : dataList) {
            ExtensionElement notifyElement = ExtensionElementUtils.createExtensionElement(map, "notify");
            task.getExtensionElements()
                    .computeIfAbsent("notify", k -> new ArrayList<>())
                    .add(notifyElement);
        }
        if (formProperties != null) {
            task.getFormProperties().addAll(formProperties);
        }
        return task;
    }
}